#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <vector>
void *threadRun(void *atr)
{
    int cnt = 5;
    while (cnt)
    {
        std::cout << (char *)atr << " is running..., pid is " << getpid() << std::endl;
        cnt--;
        sleep(1);
    }

    // 线程终止方式一：
    // return atr;
    // 线程终止方式二：等价于方式一。
    pthread_exit(atr);

    // 错误的线程终止方式：
    // exit(-1);
}

void *Otherthread(void *atr)
{
    std::cout << (char *)atr << "detach啦..." << std::endl;
    int n = pthread_detach(pthread_self());
    if (n == 0)
        std::cout << "分离成功" << std::endl;
    else
        std::cout << "分离失败" << std::endl;
    int cnt = 3;
    while (cnt)
    {
        std::cout << (char *)atr << " is running..., pid is " << getpid() << std::endl;
        cnt--;
        sleep(1);
    }
    return atr;
}
int main()
{
    // 1.创建10个线程：
    std::vector<pthread_t> vt;
    for (int i = 0; i < 10; i++)
    {
        pthread_t tid;
        // 这里推介使用堆上的变量：
        char *name = new char[128];
        snprintf(name, 128, "thread-%d", i + 1);
        pthread_create(&tid, nullptr, threadRun, (void *)name);
        vt.push_back(tid);
    }

    // 2.线程的等待：线程如果不等待，且主线程一直在运行，就有会内存泄露的问题：
    for (auto &k : vt)
    {
        void *result = nullptr;
        // 线程终止方式三：本质是线程的取消，返回值是有符号整数，-1：
        // pthread_cancel(k);
        int n = pthread_join(k, &result);
        if (n == 0)
        {
            std::cout << "等待" << (char *)result << "成功啦" << std::endl;
            // delete或者说free一个void*的指针是不可取的：这是因为delete需要根据类型去调用析构函数，以及确定需要释放多少空间！
            delete (char *)result;

            // std::cout << "thread cancel->" << (long long int)result << std::endl;
        }
        else
            std::cout << "Thread pthread_join fail！！！" << std::endl;
    }

    // 3.测试线程的分离：
    std::cout << "测试线程的分离" << std::endl;
    pthread_t tid;
    pthread_create(&tid, nullptr, Otherthread, (void *)"Detached-Thread");
    //被detach的线程（1）不能被等待；（2）不推介创建即等待，这可能会产生意料之外的结果；
    //sleep(1);
    void *koko = nullptr;
    int n = pthread_join(tid, &koko);
    if (n == 0)
        std::cout << (char *)koko << "等待成功" << std::endl;
    else
        std::cout << "等待失败，n->" << n <<std::endl;
    return 0;
}